package org.footballmanager.pandafootball.common.converter;

import lombok.Getter;
import org.springframework.core.convert.converter.Converter;
import org.springframework.core.convert.converter.ConverterFactory;

import java.util.HashMap;
import java.util.Map;
import java.util.WeakHashMap;

/**
 * @author chenjian
 * @since 2017年10月18日下午5:17:22
 */
public class UniversalEnumConverterFactory implements ConverterFactory<Integer, BaseEnum> {
    private static final Map<Class, Converter> converterMap = new WeakHashMap<>();

    /**
     * 转换器
     *
     * @param targetType 参数
     * @param <T>        参数
     * @return 返回值
     */
    @Override
    public <T extends BaseEnum> Converter<Integer, T> getConverter(Class<T> targetType) {
        Converter<Integer, T> result = converterMap.get(targetType);
        if (result == null) {
            result = new IntegerStrToEnum<>(targetType);
            converterMap.put(targetType, result);
        }
        return result;
    }

    /**
     * 内部类
     *
     * @param <T> 参数
     */
    @Getter
    class IntegerStrToEnum<T extends BaseEnum> implements Converter<Integer, T> {
        protected final Class<T> enumType;
        protected Map<Integer, T> enumMap = new HashMap<>();

        /**
         * 转换为整形
         *
         * @param enumType 参数
         */
        private IntegerStrToEnum(Class<T> enumType) {
            this.enumType = enumType;
            T[] enums = enumType.getEnumConstants();
            for (T e : enums) {
                enumMap.put((Integer) e.getValue(), e);
            }
        }

        /**
         * 转换器
         *
         * @param source 参数
         * @return 返回值
         */
        @Override
        public T convert(Integer source) {
            T result = enumMap.get(source);
            if (result == null) {
                throw new IllegalArgumentException("No element matches " + source);
            }
            return result;
        }

    }
}
